﻿namespace Socket.Core
{
    using System;
    using System.Runtime.CompilerServices;

    public abstract class AbstractSession : IDisposable, ISession
    {
        private string _sessionId;
        private bool disposed;

        public event EventHandler Released;

        protected AbstractSession(object sAEAOrEndPoint)
        {
            this.UserToken = new Socket.Core.UserToken();
            this.SAEAOrEndPoint = sAEAOrEndPoint;
        }

        private void Close()
        {
            if (this.ReceiveData != null)
            {
                this.ReceiveData.Dispose();
            }
            this.SAEAOrEndPoint = null;
            this.UserToken = null;
            this.ReceiveData = null;
        }

        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed && disposing)
            {
                this.Close();
            }
            this.disposed = true;
        }

        ~AbstractSession()
        {
            this.Dispose(false);
        }

        public virtual string GetSessionId()
        {
            return Guid.NewGuid().ToString();
        }

        public virtual void InitReceive()
        {
            if (this.ReceiveData != null)
            {
                this.ReceiveData.Dispose();
            }
            this.ReceiveData = null;
        }

        public bool IsLogin(string userTokenId)
        {
            return !string.IsNullOrEmpty(this.UserToken.UserTokenId);
        }

        public void Login(string userTokenId)
        {
            this.UserToken.Login(userTokenId);
        }

        protected virtual void OnRelease()
        {
            if (this.Released != null)
            {
                this.Released(this, new EventArgs());
            }
        }

        public virtual void Release()
        {
            this.OnRelease();
        }

        public abstract bool Send(IMessage message);
        public override string ToString()
        {
            return this.SAEAOrEndPoint.ToString();
        }

        public abstract bool IsConnected { get; }

        public IReceiveInfo ReceiveData { get; set; }

        public abstract string RemoteEndPoint { get; protected set; }

        public abstract string RemoteIp { get; protected set; }

        public object SAEAOrEndPoint { get; protected set; }

        public string SessionId
        {
            get
            {
                if (this._sessionId == null)
                {
                }
                return (this._sessionId = this.UserToken.SessionId);
            }
            protected set
            {
                this._sessionId = value;
            }
        }

        public Socket.Core.UserToken UserToken { get; private set; }
    }
}

